1. Introduction
This section is non-normative.
As the web has evolved there have been ongoing privacy-oriented changes (e.g Safari, Firefox, Chrome) and changes to the underlying privacy principles (e.g. Privacy Model).
With this evolution, fundamental assumptions of the web platform are being redefined or removed. Access to cookies in a third-party context are one of those assumptions. While overall good for the web, the third-party cookie deprecation removes a fundamental building block used by certain designs of federated identity.
The Federated Credential Management API aims to bridge the gap for the federated identity designs which relied on third-party cookies. The API provides the primitives needed to support federated identity when/where it depends on third-party cookies, from sign-in to sign-out and revocation.
In order to provide the federated identity primitives without the use of third-party cookies the API places the User Agent as a mediator between RPs and IDPs. This mediation requires user consent before permitting the RPs and IDPs to know about their connection to the user.
The specification leans heavily on changes in the User Agent and IDP and minimally on the RP. The FedCM API provides a way to authenticate, fetch tokens, revoke the provided tokens, and allow for front-channel logout.
1.1. Use Cases
The below use case scenarios illustrate some basic supported flows. Each supported flow below occurs inside an iframe or in an XHR request. Additional scenarios, including sample code, are given in the Identity Use Cases in Browser Catalog.
1.1.1. Sign-up
A Sign-up occurs when the user is registering a new account at the Relying Party using their Identity Provider.
For instance, a user navigates to a Relying Party in their browser and creates an account. The Relying Party displays supported Identity Providers to the user who selects their favorite. The user is prompted "Do you want to create an account with the Relying Party?". Upon user agreement an account is created with the Relying Party and the user has a session initialized.
1.1.2. Sign-in
After a user navigates to a Relying Party in a browser and decides to create an account by going through their § 1.1.1 Sign-up flow, there are two ways a user logs into their account once their session expires:
1.1.2.1. Auto Sign-in
Auto Sign-in occurs when the Identity Provider has already gathered permissions from the user to share their identity with the Relying Party and automatically signs the user in.
For example, the user has previously executed the § 1.1.1 Sign-up flow and then changes from their phone to their laptop. On the new device the user goes to the Relying Party and selects to sign-in using their Identity Provider. The Identity Provider knows, and proves, the user has signed up to the Relying Party and the Relying Party creates a new session for the users account.
1.1.2.2. Explicit Sign-in
An explicit sign-in occurs when the Identity Provider believes it is necessary to gather an explicit permission from the user to sign into a Relying Party, typically after the user goes through a § 1.1.3 Sign-out flow.
For example, after the user has done the § 1.1.3 Sign-out flow of the Relying Party they decide to log in again. The user visits the Relying Party and selects their Identity Provider to sign-in. The Identity Provider knows:
-
the user already has an account with the Relying Party.
-
the user has logged out of the Relying Party.
The user is then prompted, "Do you want to sign-in with the Relying Party?" and upon user agreement the Relying Party creates a new session with the users existing account.
1.1.3. Sign-out
After a user navigates to a Relying Party in a browser and decides to create an account by going through their § 1.1.1 Sign-up flow, there are two ways a user can clear their sessions:
1.1.3.1. RP Sign-out
The user can log out through the Relying Party by using a provided sign-out button or link provided by the Relying Party. This then removes the users session and, when the user visits the Relying Party again they will need to go through the § 1.1.2.2 Explicit Sign-in flow in order to establish a new session.
1.1.3.2. IDP Sign-out
The user can log out through the Identity Provider by using a provided sign-out system provided by the Identity Provider. After using the sign-out system the Identity Provider will log the user out of all Relying Parties the user has signed into along with logging the user out of the Identity Provider itself. Upon returning to any associated Relying Party, or the Identity Provider, the user will have to go through the § 1.1.2.2 Explicit Sign-in flow.
1.1.4. Revocation
After a user has created an account with a Relying Party there are two ways a user can cancel their account with the Relying Party:
1.1.4.1. RP Revocation
The user can delete their account through the Relying Party by using the provided cancel account system. The Relying Party informs the Identity Provider that the user has deleted (revoked) their account. When the user returns to the Relying Party they will need to complete the § 1.1.1 Sign-up flow in order to access the site.
1.1.4.2. IDP Revocation
The user can delete their account with a Relying Party by revoking Relying Party access through the Identity Provider. This can be done by going to the Identity Provider and using their revoke access system. Once access is revoked, when the user returns to the Relying Party they will need to complete the § 1.1.1 Sign-up flow in order to access the site.
1.1.5. Access
The Identity Provider while authenticating the user may also authorize access to users resources such as calendars, contacts, etc. The granting of access can be done at either sign-up or post sign-up by requesting permission from the user.
For example, a user executes the § 1.1.1 Sign-up flow with a Relying Party. During the flow the Relying Party has informed the Identity Provider they need calendar access for the user. The user will be presented with a prompt, "Do you want to give access to your Calendar to the Relying Party?". The user consents to providing access and when the flow is complete the Relying Party shows the user their calendar entries provided by the Identity Provider.
2. Examples
This specification defines a new IdentityCredential type and internal
algorithms to allow the exchange of identity between IDPs and RPs.
When it succeeds, it returns to the RP a signed id token which the RP can use to authenticate the user.
3. Single Account Example
< html > < head > < title > Welcome to my Website</ title > </ head > < body > < button onclick = "login()" > Login with idp.example</ button > < script > async function login() { // This will prompt when !credential["registered"], but // it won’t when credential["registered"]. // If the user selects an account updates the credential["registered"] // state and stores any needed account information. // The object will be either registered or unregistered and store information // on if the user should be prompted based on the mediation flag. // TODO: the use of the mediation flag isn’t fully speced out yet. return await navigator. credentials. get({ mediated: “optional”, // “optional” is the default identity: { providers: [{ configURL: "https://idp.example/manifest.json" , clientId: "123" , nonce: "456" }] } }); } </ script > </ body > </ html >
4. Multiple Account Example
< html > < head > < title > Welcome to my Website</ title > </ head > < body > < button onclick = "login()" > Login with idp.example</ button > < button onclick = "multiLogin()" > Switch account</ button > < script > async function login() { const id= ...; /* site gets stored id if available */ const credential= await navigator. credentials. get({ mediation: "optional" , identity: { providers: [{ configURL: "https://idp.example/manifest.json" , clientId: "123" , hint: id, nonce: "456" , }] } }); /* site stores credential id somewhere */ return credential; } async function multiLogin() { const credential= await navigator. credentials. get({ mediation: "required" , identity: { providers: [{ configURL: "https://idp.example/manifest.json" , clientId: "123" , nonce: "456" , }] } }); /* site stores credential id somewhere */ return credential; } </ script > </ body > </ html >
5. Terminology
HTML Standard defines an origin as the tuple of a scheme, hostname, and port that provides the main security boundary on the web.
- account
-
TODO(goto): find existing definition.
- authentication
-
Process used by an Identity Provider to achieve sufficient confidence in the binding between the user and a presented identity.
Note that in some discussions and documentation, the term _authentication_ is used to refer to the federated sign-in process. However, the user does not authenticate to the RP during federated sign-in. The user authenticates to the IDP, which then provides a claim to the RP asserting the user’s identity. The user does not prove their identity to the RP.
See also:
- client id
-
Each IDP assigns to each RP a client id to uniquely identify the RP. Note that this ID is dependent on both the IDP and the RP, but the client id of an RP only needs to be unique with respect to any other client id within the same IDP.
- directed identifier
-
A user identifier that that is unique for each site the user visits. A goal of anti-tracking policy is to promote user identifiers to become directed identifiers. See the § 11.2 Privacy Threat Model for more information.
- first party
-
The first-party for a user action is the party that controls the origin of the top-level browsing context under which the action happened. Intuitively, this is the owner of the domain in the browser’s URL bar.
This differs from Mozilla’s definition in that Mozilla defines other parties as first parties if the user can easily discover which party it is and intends to interact with that party, for example to allow sign-in widgets to be first-party.
- global identifier
-
A string that identifies a particular user independent of which site they’re visiting (e.g. email addresses and phone numbers). Users generally have relatively few global identifiers and can usually list and recognize them. A goal of anti-tracking policy is to prevent user identifiers from becoming global identifiers.
- high-level API
-
A use case specific API, as opposed to a low-level API. See also high level vs low level.
- id token
-
TODO(goto): find existing definition.
- Identity Provider
- IDP
-
A service that has information about the user and can grant that information to Relying Parties.
See also:
- joining
-
TODO(goto): find existing definition.
- low-level API
-
A general purpose API, as opposed to a high-level API. See also high level vs low level
- minting
- minted
-
The act of a new token being creating
- out-of-band
-
Outside of the user agent’s context.
- party
-
Defined by Tracking Preference Expression (DNT) as "a natural person, a legal entity, or a set of legal entities that share common owner(s), common controller(s), and a group identity that is easily discoverable by a user."
- Relying Party
- RP
- Website
- RP
-
A service that requests user information from an Identity Provider for federated sign-in or for other purposes.
See also:
- session
-
TODO(goto): find existing definition.
- Federated sign-in
-
Process used by a Relying Party to obtain a user identifier from an Identity Provider to which the user performed authentication.
See also:
- site
-
A set of origins that are all same site with each other. Note that there are problems (Public Suffix List Problems) with using registrable domains as a logical boundary.
- third party
-
A third-party for a user action is any party that isn’t the first party or the user (the second party).
-
unsanctioned tracking - user
-
A human or program that controls a user agent.
- user identifier
-
A pair of a site and a (potentially-large) integer allocated by that site that is used to identify a user on that site. A single user will generally have many user IDs that refer to them, and a single site may or may not know that multiple user identifiers refer to the same user.
- Privacy Policy
-
The policies described at
privacy_policy_url. - Terms of Service
-
The policies described at
terms_of_service_url. - logged-out
-
An account is
logged-outif the user has either not signed into the account or has signed out. - logged-in
-
An account is
logged-inif the user has successfully signed into the account. - registered
-
The account is
registeredif the user agent thinks that the user has registered an account in the RP using the account from the IDP. - unregistered
-
The account is
unregisteredif it’s not registered.
6. High Level Design
At a high level, the Identity Federation Management API works by the intermediation of cooperating IDPs and RPs.
The § 7 The Identity Provider API and the § 8 The Relying Party API defines a set of HTTP APIs that cooperating IDPs and IDPs exposes as well as the entry points in the § 9 The Browser API that they can use.
The user agent intermediates in such a matter that makes it impractical for the API to be used for tracking purposes, while preserving the functionality of identity federation.
This document defines the APIs in the following order:
7. The Identity Provider API
The IDP proactively and cooperatively exposes itself as a comformant agent by exposing a series of HTTP endpoints:
-
A § 7.1 Manifest endpoint in an agreed upon location that points to
-
An § 7.2 Accounts List endpoint
-
A § 7.3 Client Metadata endpoint
-
An § 7.4 ID Token endpoint
7.1. Manifest
The manifest discovery endpoint is an endpoint which serves as a discovery device to other endpoints provided by the IDP.
The manifest discovery endpoint is fetched:
(a) without cookies, (b) with a special § 7.5 Sec-FedCM-CSRF header, (c) without a Referer header, and (c) without following HTTP redirects.
For example:
The file is parsed expecting Manifest JSON object.
The Manifest JSON object has the following properties:
accounts_endpoint(required)-
A URL that points to an HTTP API that complies with the § 7.2 Accounts List API.
client_metadata_endpoint(required)-
A URL that points to an HTTP API that complies with the § 7.3 Client Metadata API.
id_token_endpoint(required)-
A URL that points to an HTTP API that complies with the § 7.4 ID Token API.
branding(optional)-
A set of Branding JSON options.
The Branding JSON enables an IDP to express their branding preferences, which may be used by User Agents to customize the user agent consent prompt.
Note: The branding preferences are deliberately designed to be high level / abstract (rather than opinionated about a specific UI structure), to enable different User Agents to offer different UI experiences and for them to evolve independently over time.
It may have the following properties:
background_color(optional)color(optional)-
color for text on IDP branded widgets using background_color.
icons(optional)-
A list of Icon JSON objects.
The Icon JSON may have the following properties:
url(required)-
The url pointing to the icon image. The icon needs to comply with the maskable specification.
size(optional)-
The size of the icon. The icon is assumed to be square and single resolution (not a multi-resolution .ico). The size may be omitted if the icon is in a vector graphic format (like SVG).
The color is a subset of CSS <color> syntax, namely <hex-color>s, hsl()s, rgb()s and <named-color>.
For example:
{ "accounts_endpoint" : "/accounts.php" , "client_metadata_endpoint" : "/metadata.php" , "id_token_endpoint" : "/idtokens.php" , "branding" : { "background_color" : "green" , "color" : "0xFFEEAA" , "icons" : [{ "url" : "https://idp.example/icon.ico" , "size" : 10 }] } }
7.2. Accounts List
The accounts list endpoint provides the list of accounts the user has at the IDP.
The accounts list endpoint is fetched (a) with IDP cookies, (b) with a special § 7.5 Sec-FedCM-CSRF header, (c) without a Referer header, and (d) without following HTTP redirects.
For example:
GET /accounts_list.php HTTP / 1.1 Host : idp.example Accept : application/json Cookie : 0x23223 Sec-FedCM-CSRF : ?1
The response is expected to have the following properties:
accounts(required)-
A list of Account JSON.
Every Account JSON is expected to have the following properties:
id(required)-
The account unique identifier.
name(required)-
The user’s full name.
email(required)-
The user’s email address.
given_name(optional)-
The user’s given name.
approved_clients(optional)-
A list of RPs (in the form of Client IDs) this account is already registered with. Used in the sign-up to allow the IDP to control whether to show the Privacy Policy and the Terms of Service.
For example:
{ "accounts" : [{ "id" : "1234" , "given_name" : "John" , "name" : "John Doe" , "email" : "john_doe@idp.example" , "picture" : "https://idp.example/profile/123" , "approved_clients" : [ "123" , "456" , "789" ] }, { "id" : "5678" , "given_name" : "Johnny" , "name" : "Johnny" , "email" : "johnny@idp.example" , "picture" : "https://idp.example/profile/456" "approved_clients" : [ "abc" , "def" , "ghi" ] }] }
7.3. Client Metadata
The client metadata endpoint provides metadata about RPs.
The client medata endpoint is fetched (a) without cookies, (b) with a special § 7.5 Sec-FedCM-CSRF header, (c) with a Referer header indicating the RP's origin (as if Referer-Policy: strict-origin was in use), and (d) without following HTTP redirects.
The user agent also passes the client_id.
For example:
GET /client_medata.php?client_id=1234 HTTP / 1.1 Host : idp.example Referer : https://rp.example/ Accept : application/json Sec-FedCM-CSRF : ?1
The file is parsed expecting the following properties:
privacy_policy_url(optional)-
A link to the RP's privacy policy.
terms_of_service_url(optional)-
A link to the RP's terms of service.
For example:
{ "privacy_policy_url" : "https://rp.example/clientmetadata/privacy_policy.html" , "terms_of_service_url" : "https://rp.example/clientmetadata/terms_of_service.html" }
7.4. ID Token
The ID Token endpoint is responsible for minting a new id token for the user.
The ID Token endpoint is fetched (a) as a POST request, (b) with IDP cookies, (c) with a Referer header indicating the RP's origin (as if Referer-Policy: strict-origin was in use), (d) with a special § 7.5 Sec-FedCM-CSRF header, and (e) without following HTTP redirects.
It will also contain the following parameters in the request body application/x-www-form-urlencoded:
client_idnonce-
The request nonce
account_id-
The account identifier that was selected.
disclosure_text_shown-
Whether the user agent has explicitly shown to the user what specific information the IDP intends to share with the RP (e.g. "idp.example will share your name, email.... with rp.example"), used by the sign-up algorithm for new users but not by the sign-in algorithm for returning users.
For example:
POST /fedcm_token_endpoint HTTP / 1.1 Host : idp.example Referer : https://rp.example/ Content-Type : application/x-www-form-urlencoded Cookie : 0x23223 Sec-FedCM-CSRF : ?1 account_id=123&client_id=client1234&nonce=Ct60bD&disclosure_text_shown=true
The response is parsed as a JSON file expecting the following properties:
id_token-
The resulting id token.
For example:
7.5. Sec-FedCM-CSRF
Sec-FedCM-CSRFAll FedCM HTTP requests sent by the browser must contain a header Sec-FedCM-CSRF with value ?1. This allows servers to verify that the request
was initiated by the browser and not untrusted JavaScript because
it is a forbidden header name.
8. The Relying Party API
RP's expose a § 8.1 Logout to facilitate with § 1.1.3.2 IDP Sign-out.
8.1. Logout
When IDPs call the § 9.4.1 IDP Sign-out API, every RP gets a chance to log the user out (e.g. clear cookies, clear local storage) via the logout endpoint.
The logout endpoint is an endpoint that is registered with the IDP out-of-band.
The logout endpoint is called (a) with a GET and (b) with the RP's cookies.
Note: the logout API introduces a credentialed request from the IDP to the RPs, so it exposes a potential tracking surface area. It is a fairly limited and controlled tracking area because the logout API is only available when accounts and sessions are already established between the IDP and the RP.
9. The Browser API
The Browser API exposes APIs to RPs and IDPs to call and intermediates the exchange of the user’s identity.
The Sign-up and Sign-in APIs are used by the Relying Partys to ask the browser to intermediate the relationship with the Identity Provider and the provisioning of an id token.
NOTE: The Relying Party makes no delineation between Sign-up and Sign-in, but rather calls the same API indistinguishably.
If all goes well, the Relying Party receives back an IdentityCredential which contains an id token in the form of a signed JWT which it can use to
authenticate the user.
const credential= await navigator. credentials. get({ identity: { providers: [{ url: "https://idp.example/manifest.json" , clientId: "123" , hint: "dan@example.com" }] } });
To do so, this specification does three things:
First, it introduces a new Credential type, called § 9.2 The IdentityCredential Interface.
Second, it introduces an extension to § 9.3 The CredentialRequestOptions.
Lastly, it overrides the default implementation of § 9.4 The [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) internal method.
9.1. The State Machine
Internally, the FedCM API manages a set of credentials which are associated with an RP and IDP pair. Those credential objects have different stages of their accounts. At each stage, the state machine manages the credentials access to the appropriate browser capabilities.
TODO: add an ASCII image to explain how the states fit into the algorithms.
The user agent keepts track of the following state machine for each (account, RP) pair:
Account State-
Keeps track of whether the user has registered the account in the RP or not. Can be registered or unregistered (by default).
Session State-
Keeps track of whether the user has an open or closed session. Can be logged-in or logged-out (by default).
9.2. The IdentityCredential Interface
This specification introduces a new type of Credential, called an IdentityCredential:
[Exposed =Window ,SecureContext ]interface :IdentityCredential Credential {readonly attribute USVString ?; };idToken
idToken-
The
idToken's attribute getter returns the value it is set to. It represents the minted ID token provided by the IDP.
The main entrypoint in this specification is through the entrypoints exposed by the Credential Management API.
9.3. The CredentialRequestOptions
This specification starts by introducing an extension to the CredentialRequestOptions object:
partial dictionary CredentialRequestOptions {IdentityCredentialRequestOptions ; };identity
The IdentityCredentialRequestOptions contains a list of IdentityProviders that the Relying Party supports and has
pre-registered with (i.e. it has a clientId).
dictionary {IdentityCredentialRequestOptions sequence <IdentityProvider >; };providers
Each IdentityProvider represents an Identity Provider that
the Relying Party supports (e.g. that it has a pre-registration agreement with).
dictionary {IdentityProvider required USVString ;configURL required USVString ;clientId USVString ;nonce USVString ; };hint
url-
The URL of the identity provider.
clientIdnonce-
A random number of the choice of the RP. TODO: expand on how this is intended to be used.
hint-
Optional
accountIdhint. Maybe used by the UA when displaying the account chooser dialog.
9.4. The [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) internal method
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)This algorithm runs in parallel inside the Credential Management § algorithm-request to request
credentials and returns a set of IdentityCredential for the requested Identity Providers.
This internal method accepts three arguments:
origin-
This argument is the relevant settings object's origin, as determined by the calling
get()implementation, i.e.,CredentialsContainer's Request aCredentialabstract operation. options-
This argument is a
CredentialRequestOptionsobject whoseoptions.member contains anidentityIdentityCredentialRequestOptionsobject specifying the exchange options. sameOriginWithAncestors-
This argument is a Boolean value which is
trueif and only if the caller’s environment settings object is same-origin with its ancestors. It isfalseif caller is cross-origin.
NOTE: The mediation flag is currently not used.
The signal is used as an abort signal for the
requests.
When this method is invoked, the user agent MUST execute the following algorithm:
-
If sameOriginWithAncestors is
false, return a "NotAllowedError"DOMException.Note: This restriction aims to address the concern raised in Security Origin Confusion.
-
Assert: options["
identity"]["providers"] size is 1.Note: At some point we would like to support choosing accounts from multiple Identity Providers.
-
Let hint be provider["
hint"] -
Let credential be a new
IdentityCredential. -
Set credential’s provider to provider.
-
Set credential’s
idto hint. -
Request user consent by running the request consent algorithm with the provider.
-
If
Account Stateis unregistered then return null. -
Let token be the result of running the create tokens algorithm.
-
Set credential’s
idTokento token. -
return credential.
To request consent:
-
Let manifest be the result of running the fetch the manifest algorithm with provider.
-
Let accounts list be the result of running the fetch the accounts list algorithm.
-
Let account be the result of running the select an account from the accounts list algorithm.
-
If account is null, return.
-
If the
Account Stateis unregistered then run the sign-up algorithm for account, and return. -
Run the sign-in algorithm for account.
To fetch the accounts list:
-
Let the accounts_endpoint url be the relative url manifest["
accounts_endpoint"] of provider["configURL"] -
Let the accounts list be the result of fetching the accounts_endpoint with the Identity Provider's cookies. This request MUST NOT follow HTTP redirects and instead abort with an error if there are any. See also § 7.2 Accounts List. TODO: explain why we must not follow redirects in the security section.
-
Return the accounts list.
To sign-up the user with a given account:
-
Let metadata be the result of running the fetch the client metadata algorithm.
-
If metadata["
privacy_policy_url"] is defined and the provider["clientId"] is not in the list of account["approved_clients"] then display the metadata["privacy_policy_url"] link. -
If metadata["terms_of_service_url"] is defined and the provider["
clientId"] is not in the list of account["approved_clients"] then display the metadata["terms_of_service_url"] link. -
Prompt the user to gather explicit intent to create an account. The user agent MAY use the Branding JSON to inform the style choices of its UI.
-
Set the account’s
Account Statefrom unregistered to registered. -
Set the account’s
Session Statefrom logged-out to logged-in.
To fetch the client metadata:
-
Let the client_metadata_endpoint url be the relative url manifest["
client_metadata_endpoint"] of provider["configURL"] -
Let the policies be the result of fetching the client_metadata_endpoint with the Sec-FedCM-CSRF header but without the Identity Provider's cookies. This request MUST NOT follow HTTP redirects and instead abort with an error if there are any. See also § 7.3 Client Metadata.
-
Return policies.
To select an account from the accounts list:
-
If accounts list’s size is 1:
-
Let account be accounts list[0] and return account
-
-
If this’s provider["
hint"] is provided and an account matches this’s account["accountId"] then return account. -
Display an account chooser
-
Let account be an account that the user manually selects from the accounts chooser, or null if no account is selected.
-
Return account
To sign-in the user:
-
Assert that the
Account Stateis registered -
Set the account’s
Session Statefrom logged-out to logged-in.
To create tokens:
-
Assert
Account Stateis registered -
Assert
Session Stateis logged-in -
Let request be a new object
-
Let tokens be the result of making a POST request described in § 7.4 ID Token.
-
Return tokens["id_token"].
The fetch the manifest algorithm accepts an IdentityProvider provider and returns a Manifest object:
-
In parallel, perform the following two steps:
-
Let manifestInSet be the result of running check the root manifest, passing provider.
-
Let manifest be the result of running fetch the internal manifest, passing provider.
-
-
If manifestInSet is true, return manifest, otherwise abort with an error.
NOTE: We use a two-tier manifest list in order to prevent the IDP to easily determine the RP that a user is visiting by encoding the information in the manifest path. We solve this issue by requiring a manifest list to be on the root of the IDP. The manifest itself can be anywhere, but it will not be used if the user agent does not find it in the manifest list. This allows the IDP to keep their actual manifest on an arbitary path while allowing the user agent to prevent manifest manipulation to fingerprint. See https://github.com/fedidcg/FedCM/issues/230 for more details on this attack.
The check the root manifest accepts an IdentityProvider provider and whether the manifest is included in the manifest list:
-
Let url be provider’s
configURL. -
Let rootUrl be a new URL.
-
Set rootUrl’s host to url’s host's registrable domain.
-
Set rootUrl’s path to ".well-known/fedcm.json".
-
Let request be a new request whose url is rootUrl and redirect mode set to "error". TODO: what other fields need to be set?
-
Fetch request with processResponseConsumeBody set to the following steps given a response response:
-
If response is a network error or its status is not an ok status, return false.
-
If response’s Content-Type Metadata is not a JSON MIME Type, return false.
-
Let json be the result of parse JSON bytes to an Infra value passing response’s body.
-
If json is a parsing exception, or if json is not an ordered map, return false.
-
If json["provider_urls"] does not exist, or if it is not a list, return false.
-
If the size of json["provider_urls"] is greater than 1, return false. TODO: determine the right value, probably greater than 1.
-
If json["provider_urls"][0] is not a string, return false.
-
Return true if json["provider_urls"][0] is equal to provider’s
configURL, otherwise return false.
-
The fetch the internal manifest algorithm accepts an IdentityProvider provider and returns a Manifest:
-
Run a Content Security Policy Level 3 check with a connect-src directive on the URL passed as provider’s
configURLand return if the check fails. -
Return the result of fetching the provider’s
configURLand parsing it into a Manifest. TODO: specify how the fetching and the parsing works. The fetch MUST be done with the Sec-FedCM-CSRF header but without the Identity Provider's cookies. This request MUST NOT follow HTTP redirects and instead abort with an error if there are any.
9.4.1. IDP Sign-out
In enterprise scenarios, it is common for the user to want to clear all of their existing sessions in all of the Relying Partys they are logged into.
It does so by being navigated to their Identity Provider who initiates what’s called a Front-Channel Logout.
The browser exposes an API that takes the list of Relying Partys that the Identity Provider wants to initiate the logout which are loaded in parallel with cookies.
Each Relying Party endpoint is responsible for clearing its local state (e.g. clearing cookies).
After the completion of this API, the user’s session is cleared and will go through an § 1.1.2.2 Explicit Sign-in upon return.
await IdentityCredential. logoutRPs([{ url: "https://rp1.example" , accountId: "123" }, { url: "https://rpN.example" , accountId: "456" }]);
IDPs can call IdentityCredential.logoutRPs(...) to log the user out of the RPs they are signed into.
dictionary {IdentityCredentialLogoutRpsRequest required USVString ;url required USVString ; }; [accountId Exposed =Window ,SecureContext ]partial interface IdentityCredential {static Promise <undefined >(logoutRPs sequence <IdentityCredentialLogoutRpsRequest >); };logoutRequests
When this method is invoked, the user agent MUST execute the following algorithm:
-
Let promise be a new
Promise. -
For each request in logoutRequests
-
Let credential be a credential matching request’s
urland request’saccountId -
If no matching credential continue
-
If the credential
Account Stateis unregistered orSession Stateis logged-out continue -
POST to the request’s
urlwith the Relying Parties cookies. This request MUST NOT follow HTTP redirects and instead abort the request. -
Set the credential
Session Stateto logged-out
-
-
Resolve promise with undefined and return promise.
9.5. Backwards Compatibility
Note: go over how we are planning to deal with backwards compatibility.
10. Security
This section provides a few of the security considerations for the FedCM API. Note that there is a separate section for § 11 Privacy considerations.
10.1. Content Security Policy
The first fetches triggered by the FedCM API are the manifest list, which is public, and the internal manifest. Imagine a malicious script included by (and running as) the RP attempting to execute the FedCM API calls to a malicious IDP, one which is not trusted by the RP. If the call is successful, this would introduce browser UI on the RP with sign in options into a malicious IDP. This maliciousIDP could then attempt to trick the user. The protection against this attack is the Content Security Policy Level 3 check, which would fail because the origin of the manifest of the malicious IDP would not be an origin included in the allowlist specified by the Content Security Policy Level 3 of the RP, hence preventing the undesired FedCM UI from being shown. Since any subsequent fetches are same origin with respect to the internal manifest or at least dependent on the contents of the internal manifest, they do not require additional checks.
The non-same-origin fetches include, for example, the brand icon. The user agent does not perform a Content Security Policy Level 3 check on these because they are directly specified from the manifest. In addition, the rendering of this image is performed by the user agent, and as such this image cannot affect the RP site nor can they be inspected by the RP in any way.
10.2. Sec-FedCM-CSRF
The FedCM API introduces several non-static endpoints on the IDP, so these need to be protected from XSS attacks. In order to do so, the FedCM API introduces the § 7.5 Sec-FedCM-CSRF header, a forbidden header name. The header cannot be set by random websites, so the IDP can be confident that the request was originated by the FedCM browser rather than sent by a websites trying to run an XSS attack. An IDP must to check for this header in the credentialed requests it receives, which ensures that the request was initiated by the user agent, based on the FedCM API. A malicious actor cannot spam FedCM API calls, so this is sufficient protection for the new IDP endpoints.
10.3. Browser Surface Impersonation
The FedCM API introduces new (trusted) user agent UI, and the user agent may choose to show the UI entirely on top of the page’s contents, if anything because the page was the one responsible for this UI. This introduces a potential concern of a malicious site to try to replicate the FedCM UI, gain the user’s trust that the user is interacting with a trusted browser surface, and gather information from the user that they would only give to the browser rather than the site (e.g. usernames/passwords of another site). This is not possible because the FedCM UI uses the metadata about the user accounts of the IDP, which the website doesn’t have access. If this is a malicious site, it would not know the user accounts, otherwise the user is already compromised. In addition, the FedCM UI is deliberately constructed to not prompt the user to provide additional information, such as username or password. Thus, an attacker trying to impersonate the browser using exclusively UI that is accessible to the content area (e.g. iframes) to attempt to retrieve sensitive information from the user would be noticeably different from the FedCM UI. Finally, because the FedCM UI can only be queried from the top-level frame (or potentially from an iframe with explicit permission from the top-level frame), the priviledged UI surface is only shown when the top-level frame wants it so. A sneaky iframe cannot force the FedCM UI to occlude important content from the main page.
11. Privacy
11.1. Network requests
The FedCM API introduces the ability for a site to ask the browser to execute a few different network requests, as shown in the § 6 High Level Design section. It is important for the browser to execute these in such a way that it does not allow the user to be tracked (by an attacker impersonating an IDP) on to the site using FedCM. The following table has information about the network requests performed:
For fetches that are sent with cookies, we actually consider them equivalent to first-party fetches, and hence include first-party cookies as if the resource was loaded as a first-party, e.g. regardless of the SameSite value (which is used when a resource loaded as a third-party, not first-party). This makes it easy for an IDP to adopt the FedCM API without introducing security issues on the API, since the RP cannot inspect the results from the fetches in any way.
TODO: explain why we disable following redirects.
-
The manifest fetch can’t be used to track users because it is performed without cookies, client id, or referrer. Thus, anyone could perform this fetch, and the information contained therein is considered public.
-
The accounts fetch can’t be used to track users because it is performed with cookies from the IDP but, importantly, without the client id or referrer. This in theory is a new power that the RP gains that it would not have otherwise. Preventing too many of these fetches may be important, but IDPs are already expected to protect against DoS attacks. In addition, the user agent should only allow one FedCM flow per page at any given moment, immediately rejecting any attempts to start another one. Since a FedCM flow can only be terminated when the user interacts or after a long timer, the number of fetches performed is not a concern. The IDP does learn a lot about the user from this fetch, but this is discussed in detail below.
-
The client metadata fetch can’t be used to track users too because it is performed without cookies from the IDP, albeit with a client id and a referrer. This allows the IDP to communicate the relevant Privacy Policy and Terms of Service to the user agent, in case they need to be displayed. Again, besides possible timing attacks described here, the RP gains nothing from this fetch, and the RP could already perform this fetch if it wanted to since it involves no cookies from the IDP.
-
By design, the token fetch exposes the user at the website to the IDP: it is peformed with cookies, client id, and referrer. Because of that, it is gated on the user interacting with the user agent UI, and enables the IDP to communicate to the RP the information required to perform a federated signin/signup. It is not possible for the RP or the IDP to force the token fetch to happen without user consent, as the user agent cannot be spoofed or otherwise tricked.
11.2. Privacy Threat Model
This section is intended to provide a comprehensive overview of the privacy risks associated with federated identity on the web for the purpose of measuring the privacy risks and benefits of proposed browser intermediation designs.
See also:
11.2.1. Principals
This section describes the three principals that would participate in an invocation of the API and expectations around their behavior.
-
The User Agent implements § 9 The Browser API and controls the execution contexts for the RP and IDP content. The user agent is assumed to be trusted by the user, and transitively trusted by the RP and IDP.
-
Relying Partys (RPs) are first party websites that invoke the FedCM API for the purpose of authenticating a user to their account or for requesting information about that user. A well-behaving RP would only invoke the API following a clear user signal -- typically, clicking a sign-in button. Since any site can invoke the API, RPs cannot necessarily be trusted to limit the user information it collects or use that information in an acceptable way.
-
Identity Providers (IDPs) are third party websites that are the target of a FedCM call to attempt to fetch an ID token. Usually the IDP has a higher level of trust than the RP since it already has the user’s personal information, but it is possible that the IDP might use the user’s information in non-approved ways. It is possible that the IDP specified in the API call may not be an IDP the user knows about, or may not be a bona fide IDP at all, in which case it likely does not have personal user information in advance, but also might be less accountable for its behavior.
11.2.2. High-level threats
Privacy Considerations for Internet Protocols describes the following high-level privacy threats, which the TAG has adopted into Self-Review Questionnaire: Security and Privacy § threats:
- Surveillance
-
Surveillance is the observation or monitoring of an individual’s communications or activities.
- Stored Data Compromise
-
End systems that do not take adequate measures to secure stored data from unauthorized or inappropriate access.
- Intrusion
-
Intrusion consists of invasive acts that disturb or interrupt one’s life or activities.
- Misattribution
-
Misattribution occurs when data or communications related to one individual are attributed to another.
- Correlation
-
Correlation is the combination of various pieces of information related to an individual or that obtain that characteristic when combined.
- Identification
-
Identification is the linking of information to a particular individual to infer an individual’s identity or to allow the inference of an individual’s identity.
- Secondary Use
-
Secondary use is the use of collected information about an individual without the individual’s consent for a purpose different from that for which the information was collected.
- Disclosure
-
Disclosure is the revelation of information about an individual that affects the way others judge the individual.
- Exclusion
-
Exclusion is the failure to allow individuals to know about the data that others have about them and to participate in its handling and use.
These threats combine into the particular concrete threats we want web specifications to defend against, described in subsections here:
11.2.3. Attack Scenarios
This section describes the scenarios in which various agents might attempt to gain user information. It considers the possibilities when:
For the purposes of this section, a principal is considered to be participating in the collection of information if it directly or indirectly performs actions with the aim of realizing one of the above threats.
Note: An example of indirect collusion would be an RP importing a script supplied by an IDP where the IDP intends to track users.
For the purpose of discussion this document assumes that third-party cookies are disabled by default and are no longer effective for use in tracking mechanisms, and also some form of mitigations are implemented against ‘bounce tracking’ using link decoration or postMessage. Most of these scenarios consider how user tracking might happen without them.
See also:
11.2.3.1. By the RP
11.2.3.1.1. Cross-Site Correlation
Related to:
Correlation is the combination of various pieces of information related to an individual or that obtain that characteristic when combined.
This attack happens when multiple RPs collude to use their user’s data to correlate them and build a richer profile.
When a user willingly provides their full name, email address, phone number, etc, to multiple relying parties, those relying parties can collaborate to build a profile of that user and their activity across collaborating sites.
Sometimes this is referred to as joining since it amounts to a join of user ecords between the account databases of multiple RPs.
This correlation and profile-building is outside the user’s control and entirely out of the User Agent’s or IDP’s view.
-
User signs into RP1 (which sells jewelry) with an IDP, providing to RP1 their email address user@email.example
-
User signs into RP2 (which sells houses) with an IDP, providing to RP2 their email address user@email.example
-
User browses the collection of wedding rings in RP1.
-
Out of band, RP1 tells RP2 that user@email.example is shopping for wedding rings
-
User browses the housing inventory in RP2.
-
RP2 uses the fact that the user is shopping for wedding rings in RP1 to advertise and filters their housing inventory.
-
User is surprised that RP2 knows that they are shopping for wedding rings.
A generalization of § 11.2.3.1.1 Cross-Site Correlation is:
(RP Secondary Use) Relying Party uses user information for purposes not authorized by the user:
When the user agrees to allow the IDP to provide information to the RP, the consent is specific to certain purposes, such as sign-in and personalization. The RP might use that data for other purposes that the user would not expect and did not authorize, such as selling email addresses to a spam list.
Spamming risk can exist even when using directed identifiers.
11.2.3.1.2. Same-Site Identification
Identification is the linking of information to a particular individual to infer an individual’s identity or to allow the inference of an individual’s identity.
This attack happens when the Relying Party employs client state-based tracking to identify user.
Any API that exposes any kind of client state to the web risk becoming a vector for fingerprinting or ‘supercookies’.
This risk would be increased by any proposal for browser mediation that adds directly (or indirectly) detectable client state.
See also:
11.2.3.1.3. Data Compromise
This attack scenario happens when the RP takes advantage of inadequate measures (by the IDP or the UA) to secure stored data to obtain personal user information without their consent.
This can happen if user consent mechanisms are missing, inadequate, or susceptible to bypass.
See also:
11.2.3.2. By the IDP
11.2.3.2.1. Secondary Use
Related to:
Secondary use is the use of collected information about an individual without the individual’s consent for a purpose different from that for which the information was collected.
This attack happens when Identity Providers misuses the the information collected to enable sign-in for other purposes.
Existing federation protocols require that the IDP know which service is
requesting an ID token in order to allow identity federation (e.g. the IDP must
know the OAuth client_id).
Identity providers can use this fact to build profiles of users across sites where the user has decided to use federation with the same account. This profile could be used, for example, to serve targeted advertisements to those users browsing on sites that the IDP controls.
This risk can exist even in the case where the IDP does not having pre-existing user account information (for instance, if it is not a _bona fide_ IDP), because FedCM requests sent to the IDP are credentialed. This is more likely to occur if the RP is colluding with the IDP to enable tracking; expanded variants are described in § 11.2.3.3.3 Timing Attacks.
-
User signs into RP1 (which sells jewelry) with an IDP.
-
User signs into RP2 (which sells houses) with the same IDP.
-
User navigates to the IDP.
-
Because the IDP knows that the user has an account with RP1 and RP2, the IDP can show ads about vacations for honeymoons.
-
The user is surprised that their IDP is aware of their plans to get married.
11.2.3.2.2. Impersonation
Since IDPs have unconstrained ability to issue ID tokens, they are capable of logging in to users’ federated accounts without user knowledge or action, impersonating the user and potentially gaining full access to the user’s account on the RP.
-
User signs into RP1 (which is a online dating site) with an IDP.
-
An evil employee at IDP is an ex-spouse of the user.
-
The evil employee impersonates themselves as the User and gains access to RP1
-
The evil employee looks at the user’s dating history.
-
The user is surprised by their ex-spouse’s knowledge of their recent dating affairs.
11.2.3.3. By Collusion
11.2.3.3.1. Intrusion
From Target Privacy Threat Model § hl-intrusion
Privacy harms don’t always come from a site learning things.
From RFC6973: Intrusion
Intrusion consists of invasive acts that disturb or interrupt one’s life or activities. Intrusion can thwart individuals' desires to be left alone, sap their time or attention, or interrupt their activities.
In the context of federation, intrusion happens when an RP and an IDP are colluding to invasively and aggressively recommend the user to login disproportionally to the their intent.
Much like unsolicited notifications, an RP can collude with an IDP to aggressively log users in.
See also:
11.2.3.3.2. Back channel
This attack scenario happens when IDP exceed the user’s information sharing permission.
Existing federated identity protocols are clear on what information an RP is requesting, which the IDP can provide. While the browser can inspect the request and response and consider whether user permission has been granted for that transfer, it is difficult to know that there is no additional information embedded in the response. An example could be if the IDP encodes an identifier that could be used to load user-targeted advertisements on RP pages, which could be of value where the IDP has much more profiling information about the user.
Another example is if identifying information is shared out-of-band, invisible to the browser, in which case it could contain anything.
-
User signs into RP1 (which sells jewelry) with an IDP, providing to RP1 their directed identifier email address SHA256(user + RP1)@email.example
-
User signs into RP2 (which sells houses) with an IDP, providing to RP2 their directed identifier email address SHA256(user + RP2)@email.example
-
User browses the collection of wedding rings in RP1.
-
Out of band, RP1 colludes with the IDP and exchanges SHA256(user + RP1)@email.example to user@email.example.
-
RP1 tells RP2 that user@email.example is shopping for wedding rings
-
User browses the housing inventory in RP2.
-
Out of band, RP2 colludes with the IDP and exchanges SHA256(user + RP2)@email.example to user@email.example.
-
RP2 uses the fact that the user is shopping for wedding rings in RP1 to advertise and filters their housing inventory.
-
User is surprised that RP2 knows that they are shopping for wedding rings.
11.2.3.3.3. Timing Attacks
The potential for IDPs profiling users based on their visits to RPs § 11.2.3.2.1 Secondary Use can be partially mitigated by hiding the RP from the IDP until after the user has agreed to that tracking risk.
However, there is residual risk in cases where the RP and IDP are colluding.
If a credentialed request is sent to the IDP that does not explicitly identify the RP, either of the following would still allow tracking by the IDP (again, possibly not a _bona fide_ IDP that has existing knowledge of the user):
-
The RP controlling any field in the request that can be used to convey identifying data in the request that the IDP could correlate to other requests from other RPs;
-
The RP being able to provide fine-resolution timing information about the request to the IDP out of band.
The timing information can enable tracking in the following way:
-
The RP logs the time at which it invoked the API, and
-
The IDP logs the time at which it received a credentialed FedCM request from the user, and later
-
They attempt to link the invocation and the request together using that information.
Notably, this is possible without FedCM using simple cross-origin top-level navigations, but using FedCM for this purpose would worsen the problem if it improved timing resolution or was less visible to users.
See also:
11.3. Mitigation Strategies
In this section we’ll go over some strategies used in this specification to mitigate the privacy threats.
11.3.1. Minimal Disclosure
There is a series of privacy threats that can be mitigated by disclosing the least amount of identifying information and limiting its use as much as possible. Two notable strategies are described in the sections below.
11.3.1.1. Directed Identifiers
Mitigates:
Note: directed, sharding, partitioning
The problem of RPs joining user data via back-channels is inherent to the proliferation of identifying user data. This can be solved by issuing directed identifiers that provide an effective handle to a user’s identity with a given IDP that is unique and therefore cannot be correlated with other RPs.
In the past, there have been schemes to accomplish this using one-way hashes of, for example, the user’s name, the IDP and the RP.
Note: this mitigation is not robust against § 11.2.3.3.2 Back channel, or the § 11.2.3.2.1 Secondary Use. Also, collaborating RPs might be able to defeat this mitigation by sharing the same CLIENT_ID, although possibly this could be detected and presumably would violate RP agreements with IDPs with § 11.3.5 Pre-registration.
11.3.1.2. Self Presentation
Mitigates:
Note: unbundling issuing from presentation
Preventing tracking of users by the IDP is difficult because the RP has to be coded into the identity token for security reasons, to prevent reuse of the token. There have been cryptographic schemes developed to blind the IDP to the RP while still preventing token reuse in that way (see Mozilla’s personas) but there are other valid uses that the IDP has for knowing the RP, such as fraud and abuse prevention.
11.3.2. Mediation
Mitigates:
IDPs, whom the user has entrusted with their personal data, are currently responsible for ensuring that the user consents to their information being shared. With browser mediation in place, the user agent might have to assume responsibility for ensuring the user understands what is being shared and that it is intentional. This is certainly the case if the browser is able to entirely intermediate the identity flow without showing any IDP web content, but also might be desirable if there are concerns that the IDP is not collecting consent in an adequate manner.
Additionally, a consent prompt preceding the sharing of the RP’s request to the IDP can mitigate risks around IDP tracking of user visits to RPs.
See also:
-
Self-Review Questionnaire: Security and Privacy § user-mediation
-
Ethical Principles: The web must make it possible for people to verify the information they see
-
Ethical Principles: The web must enhance individuals' control and power
11.3.2.1. Verification
Mitigates:
The User Agent can mitigate § 11.2.3.1.1 Cross-Site Correlation by inspecting the contents of the data exchange, and providing the necessary user controls.
For example, it can inspect the email address that is being exchanged and verify whether it is a directed identifier or not (and warn the user proportionally).
11.3.2.2. Activation
The User Agent can mitigate § 11.2.3.3.1 Intrusion by mediating the user controls and offering them proportionally to the intent of the user or the privacy risks involved.
For example, a User Agent can choose to show a loud / disruptive modal mediated dialog when it has enough confidence of the user’s intent or show a quiet / conservative UI hint when it doesn’t.
A User Agent could also choose to control disruption of the user’s experience based on the risks involved.
For example, when a directed identifier is being exchanged it can be more confident of the unintended consequeces and offer a more aggressive user experience, whereas when global identifiers are exchanged a more conservative user experience.
See also:
11.3.3. Policy
Mitigates:
Beyond technical constraints, the browser can recognize explicit assertions by the IDP about the privacy characteristics it provides and rely on those assertions in order to guide the user appropriately. An example is a hypothetical case in which the IDP asserts it will only issue directed identifiers and will not provide identifying information to the RPs out of view of the browser. In that case the browser may not have to warn the user about sharing personalized information.
11.3.4. Denylists
Mitigates:
-
Potentially all threats, but is subject to the likelihood of bad behavior being detected, which for some might be difficult.
Any RPs or IDPs observed to be using this API to compromise user privacy in a deceptive or abusive manner could be explicitly blocked from using it, or potentially added to the SafeBrowsing blocklist so that they cannot be loaded at all.
11.3.5. Pre-registration
Mitigates:
Currently, IDPs require that an RP pre-registers and agrees to specific terms before the IDP will issue an ID token to them. This conflicts with the previous mitigation, but can provide a measure of RP accountability.
11.3.6. 2FA
Mitigates:
12. Extensibility
Note: go over the extensibility mechanisms.
13. Acknowledgements
Note: write down the Acknowledgements section.